package com.gxitsky.response;

import com.gxitsky.exception.BusinessException;
import com.gxitsky.exception.Error;
import com.gxitsky.exception.SystemError;
import lombok.Data;
import org.springframework.http.HttpStatus;

/**
 * @author gxing
 * @desc 统一响应体
 * @date 2022/2/28
 */
@Data
public class ResponseModel<T> {

    public static final int SUCCESS_CODE = HttpStatus.OK.value();

    /**
     * 响应码
     */
    private int code = SUCCESS_CODE;

    /**
     * 响应消息
     */
    private String message = "success";

    /**
     * 业务数据
     */
    private T data;

    /*-------------构造方法--------------------------*/
    public ResponseModel() {
    }

    public ResponseModel(int code, String message) {
        this.code = code;
        this.message = message;
    }

    public ResponseModel(T data) {
        this.data = data;
    }

    public ResponseModel(int code, String message, T data) {
        this.code = code;
        this.message = message;
        this.data = data;
    }

    /*----------------错误------------------------------*/
    public ResponseModel(Error error) {
        this.code = error.getCode();
        this.message = error.getMessage();
    }

    public ResponseModel(Error error, T data) {
        this.code = error.getCode();
        this.message = error.getMessage();
        this.data = data;
    }

    public ResponseModel(BusinessException ex) {
        this.code = ex.getCode();
        this.message = ex.getMessage();
    }

    /*-------------响应方法--------------------------*/
    public boolean succeed() {
        return this.code == SUCCESS_CODE;
    }

    /*-------------静态方法--------------------------*/
    public static ResponseModel<?> success() {
        return new ResponseModel<>();
    }

    public static ResponseModel<?> success(String message) {
        return new ResponseModel<>(message);
    }

    public static <T> ResponseModel<T> success(T result) {
        return new ResponseModel<>(result);
    }

    public static ResponseModel<?> fail() {
        return new ResponseModel<>(SystemError.SYS_INTERNAL_ERROR);
    }

    public static ResponseModel<?> fail(int code, String message) {
        return new ResponseModel<>(code, message);
    }

    public static ResponseModel<?> fail(Error error) {
        return new ResponseModel<>(error.getCode(), error.getMessage());
    }

    public static <T> ResponseModel<T> fail(Error error, T result) {
        return new ResponseModel<>(error, result);
    }

    public static <T> ResponseModel<T> fail(T result) {
        if (result instanceof BusinessException) {
            return new ResponseModel<>((BusinessException) result);
        }
        return new ResponseModel<>(SystemError.SYS_INTERNAL_ERROR, result);
    }

    public static ResponseModel<?> fail(String message) {
        return new ResponseModel<>(SystemError.SYS_INTERNAL_ERROR.getCode(), message);
    }

    public static ResponseModel<?> fail(BusinessException ex) {
        return new ResponseModel<>(ex);
    }

    public static <T> ResponseModel<T> fail(int errorCode, String message, T result) {
        return new ResponseModel<T>(errorCode, message, result);
    }

    /*--------------Request--------------*/
    public static ResponseModel<?> requestUirNotFound() {
        return ResponseModel.fail(SystemError.REQUEST_URI_NOT_FOUND);
    }

    public static ResponseModel<?> requestMethodNotSupport() {
        return ResponseModel.fail(SystemError.REQUEST_METHOD_NOT_SUPPORT);
    }

    public static ResponseModel<?> requestBodyConvertError() {
        return ResponseModel.fail(SystemError.REQUEST_BODY_CONVERT_ERROR);
    }

    public static ResponseModel<?> requestBodyNotReadable() {
        return ResponseModel.fail(SystemError.REQUEST_BODY_NOT_READABLE);
    }

    public static ResponseModel<?> requestBodyLengthOutRange() {
        return ResponseModel.fail(SystemError.REQUEST_BODY_LENGTH_OUT_RANGE);
    }

    public static ResponseModel<?> requestContentTypeNotSupport() {
        return ResponseModel.fail(SystemError.REQUEST_CONTENT_TYPE_NOT_SUPPORT);
    }

    public static ResponseModel<?> requestParamValidError() {
        return ResponseModel.fail(SystemError.REQUEST_PARAM_VALID_ERROR);
    }

    public static ResponseModel<?> requestParamValidError(String message) {
        return ResponseModel.fail(SystemError.REQUEST_PARAM_VALID_ERROR, message);
    }

    public static ResponseModel<?> requestParamTypeError() {
        return ResponseModel.fail(SystemError.REQUEST_PARAM_TYPE_ERROR);
    }

    public static ResponseModel<?> requestParamTypeError(String message) {
        return ResponseModel.fail(SystemError.REQUEST_PARAM_TYPE_ERROR.getCode(), message);
    }

    /*---------------------Method Arg------------------------------*/
    public static ResponseModel<?> methodArgException() {
        return ResponseModel.fail(SystemError.METHOD_ARG_EXCEPTION);
    }

    public static ResponseModel<?> methodArgTypeMismatchException() {
        return ResponseModel.fail(SystemError.METHOD_ARG_TYPE_MISMATCH_EXCEPTION);
    }

    public static ResponseModel<?> methodArgNumberFormatException() {
        return ResponseModel.fail(SystemError.METHOD_ARG_NUMBER_FORMAT_EXCEPTION);
    }


    /*---------------------数据库操作------------------------------*/
    public static ResponseModel<?> dbInsertFail() {
        return ResponseModel.fail(SystemError.DB_INSERT_FAIL);
    }

    public static ResponseModel<?> dbInsertFail(String message) {
        return ResponseModel.fail(SystemError.DB_INSERT_FAIL.getCode(), message);
    }

    public static ResponseModel<?> dbUpdateFail() {
        return ResponseModel.fail(SystemError.DB_UPDATE_FAIL);
    }

    public static ResponseModel<?> dbUpdateFail(String message) {
        return ResponseModel.fail(SystemError.DB_UPDATE_FAIL.getCode(), message);
    }

    public static ResponseModel<?> dbDeleteFail() {
        return ResponseModel.fail(SystemError.DB_DELETE_FAIL);
    }

    public static ResponseModel<?> dbDeleteFail(String message) {
        return ResponseModel.fail(SystemError.DB_DELETE_FAIL.getCode(), message);
    }

    public static ResponseModel<?> dbDuplicateKeyFail() {
        return ResponseModel.fail(SystemError.DB_DUPLICATE_KEY_FAIL);
    }

    public static ResponseModel<?> dbDuplicateKeyFail(String message) {
        return ResponseModel.fail(SystemError.DB_DUPLICATE_KEY_FAIL.getCode(), message);
    }

    public static ResponseModel<?> dbDataIntegrityViolationException() {
        return ResponseModel.fail(SystemError.DB_DATA_INTEGRITY_VIOLATION_EXCEPTION);
    }

    public static ResponseModel<?> dbDataIntegrityViolationException(String message) {
        return ResponseModel.fail(SystemError.DB_DATA_INTEGRITY_VIOLATION_EXCEPTION.getCode(), message);
    }

    /*---------------------Upload File------------------------------*/
    public static ResponseModel<?> FileUploadFail() {
        return ResponseModel.fail(SystemError.FILE_UPLOAD_FAIL);
    }

    public static ResponseModel<?> FileUploadFail(String message) {
        return ResponseModel.fail(SystemError.FILE_UPLOAD_FAIL.getCode(), message);
    }

    public static ResponseModel<?> FileUploadSizeOutOfMax() {
        return ResponseModel.fail(SystemError.FILE_UPLOAD_SIZE_OUT_MAX);
    }

    public static ResponseModel<?> FileUploadSizeOutOfMax(String message) {
        return ResponseModel.fail(SystemError.FILE_UPLOAD_SIZE_OUT_MAX, message);
    }

    /*---------------------导入导出------------------------------*/
    public static ResponseModel<?> importFail() {
        return ResponseModel.fail(SystemError.IMPORT_FAIL);
    }

    public static ResponseModel<?> importFail(String message) {
        return ResponseModel.fail(SystemError.IMPORT_FAIL.getCode(), message);
    }

    public static ResponseModel<?> importDataEmpty() {
        return ResponseModel.fail(SystemError.IMPORT_DATA_EMPTY);
    }

    public static ResponseModel<?> importDataEmpty(String message) {
        return ResponseModel.fail(SystemError.IMPORT_DATA_EMPTY.getCode(), message);
    }

    public static ResponseModel<?> exportFail() {
        return ResponseModel.fail(SystemError.EXPORT_FAIL);
    }

    public static ResponseModel<?> exportFail(String message) {
        return ResponseModel.fail(SystemError.EXPORT_FAIL.getCode(), message);
    }

}
